home *** CD-ROM | disk | FTP | other *** search
/ User's Choice Windows CD / User's Choice Windows CD (CMS Software)(1993).iso / win_m_p / mwchaos.zip / CHAOS.C < prev    next >
C/C++ Source or Header  |  1991-12-15  |  13KB  |  501 lines

  1. /******
  2. *
  3. *   module:      chaos.c
  4. *   descripton:  program that draws:
  5. *
  6. *                o  the Lorenz Attractor, a chaotic function  as seen
  7. *                   on the television show NOVA "THE STRANGE NEW
  8. *                   SCIENCE OF CHAOS"
  9. *
  10. *                o  the Pickover Attractor
  11. *
  12. *                this program is adapated from a similar program by
  13. *                Marty Belles 9-2-89
  14. *
  15. *  programmer:   Bryan A. Woodruff (Woodruff Software Systems) 6/2/90
  16. *                Copyright (c) 1990
  17. *
  18. ******/
  19.  
  20. #include <windows.h>
  21. #include <math.h>
  22. #include "chaos.h"
  23.  
  24. long FAR PASCAL WndProc(HWND, unsigned, WORD, LONG);
  25. void DrawLorenz(HWND);
  26. void DrawPickover(HWND);
  27.  
  28. int     iPrevX, iPrevY, iPrevDef;
  29. short   xClient, yClient;
  30. short   nRed, nGreen, nBlue;
  31.  
  32. /***
  33. * Lorenz Attractor Globals
  34. ***/
  35.  
  36. double  dLorX, dLorY, dLorZ, dThetaX, dThetaY, dThetaZ, dCosX, dCosY, dCosZ,
  37.         dSinX, dSinY, dSinZ;
  38.  
  39. /***
  40. * Pickover Attractor Globals
  41. ***/
  42.  
  43. double  dMinX, dMinY, dMaxX, dMaxY, dPickX, dPickY, dPickZ,
  44.         dPickA, dPickB, dPickC, dPickD, dPickE;
  45.  
  46. /***
  47. * Defaults
  48. ***/
  49.  
  50. WORD    wColor = IDD_RANDOM,
  51.         wPlane = IDD_XYPLANE,
  52.         wFunc  = IDD_PICKOVER;
  53.  
  54.  
  55. int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
  56. HANDLE  hInstance, hPrevInstance;
  57. LPSTR   lpszCmdLine;
  58. int     nCmdShow;
  59. {
  60.    HWND         hWnd;
  61.    MSG          msg;
  62.    WNDCLASS     wndclass;
  63.    static char  szAppName[] = "chaos";
  64.    static char  szVersion[] = "Chaos Generator v1.2";
  65.  
  66.    if (hPrevInstance)
  67.       return (FALSE);
  68.  
  69.    wndclass.style         = CS_HREDRAW | CS_VREDRAW;
  70.    wndclass.lpfnWndProc   = WndProc;
  71.    wndclass.cbClsExtra    = 0;
  72.    wndclass.cbWndExtra    = 0;
  73.    wndclass.hInstance     = hInstance;
  74.    wndclass.hIcon         = NULL;
  75.    wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW);
  76.    wndclass.hbrBackground = GetStockObject (WHITE_BRUSH);
  77.    wndclass.lpszMenuName  = szAppName;
  78.    wndclass.lpszClassName = szAppName;
  79.  
  80.    if (!RegisterClass(&wndclass))
  81.       return FALSE;
  82.  
  83. #ifdef MEWEL
  84.   if (WinOpenGraphics(-1) != TRUE)
  85.     return FALSE;
  86. #endif
  87.  
  88.    hWnd = CreateWindow(szAppName, szVersion, WS_OVERLAPPEDWINDOW,
  89.                         CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL,
  90.                         hInstance, NULL);
  91.  
  92.    ShowWindow(hWnd, nCmdShow);
  93.    UpdateWindow(hWnd);
  94.  
  95.    while (TRUE) {
  96.       if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) {
  97.          if (msg.message == WM_QUIT)
  98.             break;
  99.          TranslateMessage(&msg);
  100.          DispatchMessage(&msg);
  101.       }
  102.       else {
  103.          switch (wFunc) {
  104.             case IDD_LORENZ:
  105.                DrawLorenz(hWnd);
  106.                break;
  107.  
  108.             case IDD_PICKOVER:
  109.                DrawPickover(hWnd);
  110.                break;
  111.          }
  112.       }
  113.    }
  114. #ifdef MEWEL
  115.   WinCloseGraphics();
  116. #endif
  117.    return msg.wParam;
  118.  
  119. } /* end of WinMain */
  120.  
  121. /******
  122. *
  123. *     function: DrawLorenz
  124. *  description: calculates and draws Lorenz Attractor
  125. *
  126. *               *** adapted from FRACTAL PROGRAMMING IN C, pp. 87 - 90 ***
  127. *
  128. ******/
  129.  
  130. #define ONETHIRD (1.0 / 3.0)
  131.  
  132. void DrawLorenz(hWnd)
  133. HWND hWnd;
  134. {
  135.    HPEN    hPen;
  136.    HDC     hDC;
  137.  
  138.    int     iX, iY;
  139.    double  dt = 0.01, dt2 = dt / 2.0;
  140.    double  d0_x, d0_y, d0_z, d1_x, d1_y, d1_z, d2_x, d2_y, d2_z,
  141.            d3_x, d3_y, d3_z, xt, yt, zt;
  142.  
  143.    int     rand();
  144.  
  145.  
  146.    d0_x = 10.0 * (dLorY - dLorX) * dt2;
  147.    d0_y = (-dLorX * dLorZ + 28.0 * dLorX - dLorY) * dt2;
  148.    d0_z = (dLorX * dLorY - 8.0 * dLorZ / 3.0) * dt2;
  149.    xt = dLorX + d0_x;
  150.    yt = dLorY + d0_y;
  151.    zt = dLorZ + d0_z;
  152.    d1_x = 10.0 * (yt - xt) * dt2;
  153.    d1_y = (-xt * zt + 28.0 * xt - yt) * dt2;
  154.    d1_z = (xt * yt - 8.0 * zt / 3.0) * dt2;
  155.    xt = dLorX + d1_x;
  156.    yt = dLorY + d1_y;
  157.    zt = dLorZ + d1_z;
  158.    d2_x = 10.0 * (yt - xt) * dt;
  159.    d2_y = (-xt * zt + 28.0 * xt - yt) * dt;
  160.    d2_z = (xt * yt - 8.0 * zt / 3.0) * dt;
  161.    xt = dLorX + d2_x;
  162.    yt = dLorY + d2_y;
  163.    zt = dLorZ + d2_z;
  164.    d3_x = 10.0 * (yt - xt) * dt2;
  165.    d3_y = (-xt * zt + 28.0 * xt - yt) * dt2;
  166.    d3_z = (xt * yt - 8.0 * zt / 3.0) * dt2;
  167.    xt = dLorX + d3_x;
  168.    yt = dLorY + d3_y;
  169.    zt = dLorZ + d3_z;
  170.  
  171.    dLorX += (d0_x + d1_x + d1_x + d2_x + d3_x) * ONETHIRD;
  172.    dLorY += (d0_y + d1_y + d1_y + d2_y + d3_y) * ONETHIRD;
  173.    dLorZ += (d0_z + d1_z + d1_z + d2_z + d3_z) * ONETHIRD;
  174.  
  175.    switch (wColor) {
  176.       case IDD_BLACKONWHITE :
  177.          nRed   = 0;
  178.          nGreen = 0;
  179.          nBlue  = 0;
  180.          break;
  181.       case IDD_WHITEONBLACK :
  182.          nRed   = 255;
  183.          nGreen = 255;
  184.          nBlue  = 255;
  185.          break;
  186.       case IDD_RANDOM:
  187.          if (((iY < 0) && (iPrevY >= 0)) ||
  188.              ((iY > 0) && (iPrevY <= 0))) {
  189.             nRed   = (short) (rand () % 255);
  190.             nGreen = (short) (rand () % 255);
  191.             nBlue  = (short) (rand () % 255);
  192.          }
  193.    }
  194.  
  195.    hDC = GetDC(hWnd);
  196.    hPen = CreatePen(PS_SOLID, 1, RGB(nRed, nGreen, nBlue));
  197.    SelectObject(hDC, hPen);
  198.    SetMapMode(hDC, MM_ISOTROPIC);
  199.    SetWindowExt(hDC, 500, 500);
  200.    SetViewportExt(hDC, xClient / 2, -yClient / 2);
  201.    SetViewportOrg(hDC, xClient / 2, yClient / 2);
  202.    MoveTo(hDC, iPrevX, iPrevY);
  203.    switch (wPlane) {
  204.       case IDD_XYPLANE:
  205.          iX = (int)(10.0 * dLorX - 250.0);
  206.          iY = (int)(10.0 * dLorY);
  207.          break;
  208.       case IDD_YZPLANE:
  209.          iX = (int)(10.0 * dLorZ - 250.0);
  210.          iY = (int)(10.0 * dLorY);
  211.          break;
  212.       case IDD_XYZPLANE:
  213.          iX = (int)((dLorX * dSinX + dLorY * dSinY + dLorZ * dSinZ) * 10.0
  214.                      - 250.0);
  215.          iY = (int)((dLorX * dCosX + dLorY * dCosY + dLorZ * dCosZ) * 10.0);
  216.    }
  217.    if (!iPrevDef)
  218.       MoveTo(hDC, iX, iY);
  219.    LineTo(hDC, iX, iY);
  220.    iPrevX = iX;
  221.    iPrevY = iY;
  222.    iPrevDef = TRUE;
  223.    ReleaseDC(hWnd, hDC);
  224.    DeleteObject(hPen);
  225.  
  226. } /* end of DrawLorenz */
  227.  
  228. /******
  229. *
  230. *     function: DrawPickover
  231. *  description: calculates and draws Pickover Attractor
  232. *
  233. *               *** adapted from FRACTAL PROGRAMMING IN C, pp. 91 - 93 ***
  234. *
  235. ******/
  236.  
  237. void DrawPickover(hWnd)
  238. HWND hWnd;
  239. {
  240.    int     iX, iY;
  241.    double  dTempX, dTempY, dDeltaX, dDeltaY;
  242.    HDC     hDC;
  243.  
  244.    int     rand();
  245.  
  246.    dDeltaX = 500.0 / (dMaxX - dMinX);
  247.    dDeltaY = 500.0 / (dMaxY - dMinY);
  248.    dTempX = sin(dPickA * dPickY) - dPickZ * cos(dPickB * dPickX);
  249.    dTempY = dPickZ * sin(dPickC * dPickX) - cos(dPickD * dPickY);
  250.    dPickZ = dPickE * sin(dPickC * dPickX);
  251.    dPickX = dTempX;
  252.    dPickY = dTempY;
  253.    switch (wPlane) {
  254.       case IDD_XYPLANE:
  255.          iX = (int)((dPickX - dMinX) * dDeltaX);
  256.          iY = (int)((dPickY - dMinY) * dDeltaY);
  257.          break;
  258.  
  259.       case IDD_YZPLANE:
  260.          iX = (int)((dPickY - dMinX) * dDeltaX);
  261.          iY = (int)((dPickZ - dMinY) * dDeltaY);
  262.          break;
  263.    }
  264.    switch (wColor) {
  265.       case IDD_BLACKONWHITE :
  266.          nRed   = 0;
  267.          nGreen = 0;
  268.          nBlue  = 0;
  269.          break;
  270.       case IDD_WHITEONBLACK :
  271.          nRed   = 255;
  272.          nGreen = 255;
  273.          nBlue  = 255;
  274.          break;
  275.       case IDD_RANDOM:
  276.          nRed   = (short) (rand () % 255);
  277.          nGreen = (short) (rand () % 255);
  278.          nBlue  = (short) (rand () % 255);
  279.          break;
  280.    }
  281.    if ((iX >= 0) && (iX < 500) && (iY >= 0) && (iY < 500)) {
  282.       hDC = GetDC(hWnd);
  283.       SetMapMode(hDC, MM_ISOTROPIC);
  284.       SetWindowExt(hDC, 500, 500);
  285.       if (yClient > xClient)
  286.          SetViewportOrg(hDC, 0, yClient - ((yClient - xClient) / 2));
  287.       else if (xClient > yClient)
  288.          SetViewportOrg(hDC, (xClient - yClient) / 2, yClient);
  289.       else
  290.          SetViewportOrg(hDC, 0, yClient);
  291.       SetViewportExt(hDC, xClient, -yClient);
  292.       SetPixel(hDC, iX, iY, RGB(nRed, nGreen, nBlue));
  293.       ReleaseDC(hWnd, hDC);
  294.    }
  295.  
  296. } /* end of DrawPickover */
  297.  
  298. void InitializeFunction()
  299. {
  300.    switch (wFunc) {
  301.       case IDD_PICKOVER:
  302.          /* Pickover initialization */
  303.          dMaxX = 2.8;
  304.          dMinX = -2.8;
  305.          dMaxY = 2.0;
  306.          dMinY = -2.0;
  307.          dPickX = 0.0;
  308.          dPickY = 0.0;
  309.          dPickZ = 0.0;
  310.          dPickA = 2.24;
  311.          dPickB = .43;
  312.          dPickC = -.65;
  313.          dPickD = -2.43;
  314.          dPickE = 1.0;
  315.          break;
  316.  
  317.        case IDD_LORENZ:
  318.          dThetaX = 0.7853981633974;
  319.          dThetaY = 0.0;
  320.          dThetaZ = 1.570796326795;
  321.          dCosX = cos(dThetaX);
  322.          dCosY = cos(dThetaY);
  323.          dCosZ = cos(dThetaZ);
  324.          dSinX = sin(dThetaX);
  325.          dSinY = sin(dThetaY);
  326.          dSinZ = sin(dThetaZ);
  327.          dLorX = 0.0;
  328.          dLorY = 1.0;
  329.          dLorZ = 0.0;
  330.          iPrevDef = FALSE;
  331.    }
  332.  
  333. } /* end of InitializeFunction */
  334.  
  335. BOOL FAR PASCAL AboutDlgProc(hDlg, iMessage, wParam, lParam)
  336. HWND      hDlg;
  337. unsigned  iMessage;
  338. WORD      wParam;
  339. LONG      lParam;
  340. {
  341.    switch (iMessage) {
  342.       case WM_INITDIALOG:
  343.          break;
  344.  
  345.       case WM_COMMAND:
  346.          switch (wParam) {
  347.             case IDOK:
  348.                EndDialog (hDlg, 0);
  349.                break;
  350.  
  351.             default:
  352.                return FALSE;
  353.          }
  354.          break;
  355.  
  356.       default:
  357.          return FALSE;
  358.  
  359.    }
  360.    return TRUE;
  361.  
  362. } /* end of AboutDlgProc */
  363.  
  364. BOOL FAR PASCAL SettingsProc(hDlg, iMessage, wParam, lParam)
  365. HWND      hDlg;
  366. unsigned  iMessage;
  367. WORD      wParam;
  368. LONG      lParam;
  369. {
  370.    int    i;
  371.    HMENU  hMenu;
  372.  
  373.    static WORD   wOldColor, wOldPlane, wOldFunc;
  374.  
  375.    switch (iMessage) {
  376.       case WM_INITDIALOG:
  377.          wOldColor = wColor;
  378.          wOldPlane = wPlane;
  379.          wOldFunc = wFunc;
  380.          CheckRadioButton(hDlg, IDD_WHITEONBLACK, IDD_RANDOM, wColor);
  381.          CheckRadioButton(hDlg, IDD_XYPLANE, IDD_YZPLANE, wPlane);
  382.          CheckRadioButton(hDlg, IDD_LORENZ, IDD_PICKOVER, wFunc);
  383.          EnableWindow(GetDlgItem(hDlg, IDD_XYZPLANE), (wFunc == IDD_LORENZ));
  384.          break;
  385.  
  386.       case WM_COMMAND:
  387.          switch (wParam) {
  388.             case IDD_WHITEONBLACK:
  389.             case IDD_BLACKONWHITE:
  390.             case IDD_RANDOM:
  391.                wColor  = wParam;
  392.                CheckRadioButton(hDlg, IDD_WHITEONBLACK, IDD_RANDOM, wParam);
  393.                break;
  394.  
  395.             case IDD_XYPLANE:
  396.             case IDD_XYZPLANE:
  397.             case IDD_YZPLANE:
  398.                wPlane = wParam;
  399.                CheckRadioButton(hDlg, IDD_XYPLANE, IDD_YZPLANE, wParam);
  400.                iPrevDef = FALSE;
  401.                break;
  402.  
  403.             case IDD_LORENZ:
  404.             case IDD_PICKOVER:
  405.                wFunc = wParam;
  406.                CheckRadioButton(hDlg, IDD_LORENZ, IDD_PICKOVER, wParam);
  407.                EnableWindow(GetDlgItem(hDlg, IDD_XYZPLANE), (wFunc == IDD_LORENZ));
  408.                if ((wFunc == IDD_PICKOVER) && (wPlane == IDD_XYZPLANE)) {
  409.                   wPlane = IDD_XYPLANE;
  410.                   CheckRadioButton(hDlg, IDD_XYPLANE, IDD_YZPLANE, wPlane);
  411.                }
  412.                iPrevDef = FALSE;
  413.                break;
  414.  
  415.             case IDOK:
  416.                EndDialog(hDlg, TRUE);
  417.                break;
  418.  
  419.             case IDCANCEL:
  420.                wColor = wOldColor;
  421.                wPlane = wOldPlane;
  422.                wFunc = wOldFunc;
  423.                EndDialog(hDlg, TRUE);
  424.                break;
  425.  
  426.             default:
  427.                return FALSE;
  428.          }
  429.          break;
  430.  
  431.       default:
  432.          return FALSE;
  433.  
  434.    }
  435.    return TRUE;
  436.  
  437. } /* end of SettingsProc */
  438.  
  439. long FAR PASCAL WndProc(hWnd, iMessage, wParam, lParam)
  440. HWND      hWnd;
  441. unsigned  iMessage;
  442. WORD      wParam;
  443. LONG      lParam;
  444. {
  445.    int    iRow;
  446.    static FARPROC  lpfnAboutDlgProc, lpfnSettingsProc;
  447.    static HWND     hInstance;
  448.    HDC    hDC;
  449.  
  450.    void   InitializeFunction();
  451.  
  452.    switch (iMessage) {
  453.       case WM_CREATE:
  454.          hInstance = ((LPCREATESTRUCT) lParam) -> hInstance;
  455.          lpfnAboutDlgProc = MakeProcInstance(AboutDlgProc, hInstance);
  456.          lpfnSettingsProc = MakeProcInstance(SettingsProc, hInstance);
  457.          break;
  458.  
  459.       case WM_SIZE:
  460.          xClient = LOWORD(lParam);
  461.          yClient = HIWORD(lParam);
  462. #ifdef MEWEL
  463.          xClient *= FONT_WIDTH;
  464.          yClient *= VideoInfo.yFontHeight;
  465. #endif
  466.          InitializeFunction();
  467.          SetClassWord (hWnd, GCW_HBRBACKGROUND,
  468.                        GetStockObject ((wColor == IDD_BLACKONWHITE) ?
  469.                                         WHITE_BRUSH : BLACK_BRUSH));
  470.          InvalidateRect (hWnd, NULL, TRUE);
  471.          break;
  472.  
  473.       case WM_COMMAND:
  474.          switch (wParam) {
  475.             case IDM_ABOUT:
  476.                DialogBox(hInstance, "ChaosAbout", hWnd, lpfnAboutDlgProc);
  477.                break;
  478.  
  479.             case IDM_SETTINGS:
  480.                DialogBox(hInstance, "SettingsDlg", hWnd, lpfnSettingsProc);
  481.                SetClassWord (hWnd, GCW_HBRBACKGROUND,
  482.                              GetStockObject ((wColor == IDD_BLACKONWHITE) ?
  483.                                               WHITE_BRUSH : BLACK_BRUSH));
  484.                InitializeFunction();
  485.                InvalidateRect(hWnd, NULL, TRUE);
  486.                break;
  487.          }
  488.          break;
  489.  
  490.       case WM_DESTROY:
  491.          PostQuitMessage(0);
  492.          break;
  493.  
  494.       default:
  495.          return DefWindowProc (hWnd, iMessage, wParam, lParam);
  496.    }
  497.  
  498.    return 0L;
  499.  
  500. } /* end of WndProc */
  501.